

#pragma once
#include <assert.h>
#include "threadSync_t.h"
template <class T, int ALLOC_BLOCK_SIZE = 50> 
class memoryPool_t
{
public:
	static void* operator new(unsigned int size)
	{
		threadSync_t ts(&m);
		assert(sizeof(T)==size);
		assert(sizeof(T)>=sizeof(unsigned char*));
		if (!mFreePointer)
		{
			allockBlock();
		}
		unsigned char* returnPointer = mFreePointer;
		mFreePointer = *(unsigned char**)returnPointer;
		emptySize--;
		return returnPointer;
	};

	static void operator delete(void* deletePointer)
	{
		threadSync_t ts(&m);
		*(unsigned char**)deletePointer = mFreePointer;
		mFreePointer = (unsigned char*)deletePointer;
		emptySize++;
	};

protected:
	static void allockBlock()
	{
		mFreePointer = new unsigned char[sizeof(T)*ALLOC_BLOCK_SIZE];
		unsigned char** current = (unsigned char**)mFreePointer;
		unsigned char* next = mFreePointer;

		for (int i=0; i<ALLOC_BLOCK_SIZE-1; ++i)
		{
			next += sizeof(T);
			*current = next;
			current = (unsigned char**)next;
		}

		*current = 0;
		emptySize+=ALLOC_BLOCK_SIZE;
		allSize+=ALLOC_BLOCK_SIZE;
	};

protected:
	static unsigned char* mFreePointer;
	static Mutex m;
	static int emptySize;
	static int allSize;

protected:
	~memoryPool_t(){};
};

template<class T, int ALLOC_BLOCK_SIZE>
unsigned char* memoryPool_t<T,ALLOC_BLOCK_SIZE>::mFreePointer;

template<class T, int ALLOC_BLOCK_SIZE>
Mutex memoryPool_t<T,ALLOC_BLOCK_SIZE>::m;

template<class T, int ALLOC_BLOCK_SIZE>
int memoryPool_t<T,ALLOC_BLOCK_SIZE>::emptySize=0;

template<class T, int ALLOC_BLOCK_SIZE>
int memoryPool_t<T,ALLOC_BLOCK_SIZE>::allSize=0;